import { ElMessage } from 'element-plus'
import { requireImage } from '../common/vue'
import { warLoadFeatureClick } from '@/utils'

const dom = document.getElementById('cesiumContainer')
// markFeature.feature3D.label.entity.label.disableDepthTestDistance = Number.POSITIVE_INFINITY; // label不被地形遮挡
/** 测距 绘制过程 */
export function handleDistanceMeasure() {
  const viewer = window.map3DControl.viewer
  const firefightPlotStore = useFirefightPlotStore()
  const posArray: any = []

  //鼠标变成加号 颜色为红色
  if (dom) {
    dom.style.cursor = `url('${requireImage('common/red_cross.png')}') 16 16, crosshair`
  }

  // 对鼠标按下事件的监听吗，点击左键开始绘制
  viewer.screenSpaceEventHandler.setInputAction((event: any) => {
    const { cartesian } = pickPosition(viewer, event.position)
    if (!cartesian) {
      return
    }

    //笛卡尔坐标转经纬度坐标
    const ellipsoid = viewer.scene.globe.ellipsoid
    const cartographic = ellipsoid.cartesianToCartographic(cartesian)
    const obj: any = {}
    obj.lat = Cesium.Math.toDegrees(cartographic.latitude)
    obj.lng = Cesium.Math.toDegrees(cartographic.longitude)
    obj.alt = cartographic.height

    const point = [obj.lng, obj.lat, obj.alt]
    posArray.push(point)

    let pointUrl
    let scale
    let pixelOffset
    let parentName
    if (posArray.length === 1) {
      pointUrl = requireImage('common/map-start-icon.png')
      scale = 1
      pixelOffset = [0, -20]
      parentName = 'measureMarker'
    } else {
      pointUrl = requireImage('common/redCircle.png')
      scale = 0.1
      pixelOffset = [0, 0]
      parentName = 'assistPoint'
    }

    window.GPoint.add({
      name: '3', //不可重复
      parentName: parentName,
      option: {
        position: point,
        url: pointUrl, //图标地址
        scale: scale,
        pixelOffset: pixelOffset,
      },
    })

    if (posArray.length >= 2) {
      //两点之间测距

      const pointA = posArray[posArray.length - 2]
      const pointB = posArray[posArray.length - 1]

      const distance = window.cesiumMapTool
        .measureDistance(
          { lng: pointA[0], lat: pointA[1], alt: pointA[2] },
          { lng: pointB[0], lat: pointB[1], alt: pointB[2] }
        )
        .toFixed(2)

      window.GPolyline.add({
        name: '1', //不可重复
        parentName: 'measureMarker',
        option: {
          posArray: posArray,
        },
      })

      const labelPosition: Array<number> = [
        (pointA[0] + pointB[0]) / 2,
        (pointA[1] + pointB[1]) / 2,
        (pointA[2] + pointB[2]) / 2,
      ]

      const entity = viewer.entities.add({
        position: Cesium.Cartesian3.fromDegrees(
          labelPosition[0],
          labelPosition[1],
          labelPosition[2]
        ),
        label: {
          text: `直线距离：${distance}m`,
          font: '18px san-serif',
          fillColor: Cesium.Color.WHITE, //字体颜色
          outlineWidth: 2,
          disableDepthTestDistance: Number.POSITIVE_INFINITY,
        },
      })
      firefightPlotStore.currentMeasureMarkerEntity.push(entity)
    }
  }, Cesium.ScreenSpaceEventType.LEFT_CLICK)

  // 对鼠标右键按下事件的监听,右键结束绘制
  viewer.screenSpaceEventHandler.setInputAction(function () {
    // 如果小于三个点就结束绘制则提示用户
    if (posArray.length < 2) {
      return ElMessage.warning('必须绘制两个点')
    }
    //结束点
    window.GPoint.add({
      name: '2', //不可重复
      parentName: 'measureMarker',
      option: {
        position: posArray[posArray.length - 1],
        url: requireImage('common/map-stop-icon.png'), //图标地址
        scale: 1,
        pixelOffset: [0, -20],
      },
    })
    //移除标绘辅助点
    window.GPoint.removeByPatName('assistPoint')
    //鼠标变成默认
    if (dom) {
      dom.style.cursor = 'default'
    }

    //移除事件
    viewer.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK)
    viewer.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.RIGHT_CLICK)
    // 隐藏 下方提示
    const chemicalStore = useChemicalStore()
    chemicalStore.tipsPageShow = false

    warLoadFeatureClick() //监听要素点击事件
  }, Cesium.ScreenSpaceEventType.RIGHT_CLICK)
}

/** 测高 绘制过程 */
export function handleHeightMeasure() {
  const viewer = window.map3DControl.viewer
  const posArray: any = []
  const firefightPlotStore = useFirefightPlotStore()
  //鼠标变成加号 颜色为红色
  if (dom) {
    dom.style.cursor = `url('${requireImage('common/red_cross.png')}') 16 16, crosshair`
  }

  // 对鼠标按下事件的监听吗，点击左键开始绘制
  viewer.screenSpaceEventHandler.setInputAction((event: any) => {
    const { cartesian } = pickPosition(viewer, event.position)
    if (!cartesian) {
      return
    }

    //笛卡尔坐标转经纬度坐标
    const ellipsoid = viewer.scene.globe.ellipsoid
    const cartographic = ellipsoid.cartesianToCartographic(cartesian)
    const obj: any = {}
    obj.lat = Cesium.Math.toDegrees(cartographic.latitude)
    obj.lng = Cesium.Math.toDegrees(cartographic.longitude)
    obj.alt = cartographic.height

    // 存点操作
    const point = [obj.lng, obj.lat, obj.alt]
    posArray.push(point)

    // 标记两个点则结束绘制
    if (posArray.length === 2) {
      // 添加 三条线段 水平线段 垂直线段 空间直线
      // 投影点， 使用二个中较高的点位作为投影点。
      let projectionPoint
      if (posArray[1][2] > posArray[0][2]) {
        projectionPoint = [posArray[0][0], posArray[0][1], posArray[1][2]]
      } else {
        projectionPoint = [posArray[1][0], posArray[1][1], posArray[0][2]]
      }
      posArray.push(projectionPoint)
      console.log('添加测距点位', posArray)
      const pointA = posArray[0]
      const pointB = posArray[1]
      const pointC = posArray[2]

      // AB段是 空间距离, AC段是 水平高度 垂直距离 BC段是 垂直距离
      posArray.forEach((item: any, index: number) => {
        const linePosArray = []
        let textLabel = ''
        if (index === 0) {
          linePosArray.push(pointA)
          linePosArray.push(pointB)
          textLabel = '空间距离'
        } else if (index === 1) {
          linePosArray.push(pointA)
          linePosArray.push(pointC)
          textLabel = '水平高度'
        } else {
          linePosArray.push(pointB)
          linePosArray.push(pointC)
          textLabel = '垂直距离'
        }

        const distance = window.cesiumMapTool
          .measureDistance(
            { lng: linePosArray[0][0], lat: linePosArray[0][1], alt: linePosArray[0][2] },
            { lng: linePosArray[1][0], lat: linePosArray[1][1], alt: linePosArray[1][2] }
          )
          .toFixed(2)

        window.GPolyline.add({
          name: index + '', //不可重复
          parentName: 'measureMarker',
          option: {
            posArray: linePosArray,
          },
        })

        const labelPosition: Array<number> = [
          (linePosArray[0][0] + linePosArray[1][0]) / 2,
          (linePosArray[0][1] + linePosArray[1][1]) / 2,
          (linePosArray[0][2] + linePosArray[1][2]) / 2,
        ]

        const entity = viewer.entities.add({
          position: Cesium.Cartesian3.fromDegrees(
            labelPosition[0],
            labelPosition[1],
            labelPosition[2]
          ),
          label: {
            text: `${textLabel}：${distance}m`,
            font: '18px san-serif',
            fillColor: Cesium.Color.WHITE, //字体颜色
            outlineWidth: 2,
            disableDepthTestDistance: Number.POSITIVE_INFINITY,
          },
        })

        firefightPlotStore.currentMeasureMarkerEntity.push(entity)
      })
      //鼠标变成默认
      if (dom) {
        dom.style.cursor = 'default'
      }
      //移除监听左键点击事件
      viewer.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK)
      // 隐藏 下方提示
      const chemicalStore = useChemicalStore()
      chemicalStore.tipsPageShow = false

      warLoadFeatureClick() //监听要素点击事件
    }
  }, Cesium.ScreenSpaceEventType.LEFT_CLICK)
}

/** 测面 绘制过程 */
export function handleAcreageMeasure() {
  const viewer = window.map3DControl.viewer
  let gatherPolygon: any = null
  let points: any = []
  const editPoints: any = []
  let area = ''

  //鼠标变成加号 颜色为红色
  if (dom) {
    dom.style.cursor = `url('${requireImage('common/red_cross.png')}') 16 16, crosshair`
  }

  // 对鼠标按下事件的监听吗，点击左键开始绘制
  viewer.screenSpaceEventHandler.setInputAction((event: any) => {
    const { cartesian } = pickPosition(viewer, event.position)
    if (!cartesian) {
      return
    }

    //笛卡尔坐标转经纬度坐标
    const ellipsoid = viewer.scene.globe.ellipsoid
    const cartographic = ellipsoid.cartesianToCartographic(cartesian)
    const polygonObj: any = {}
    polygonObj.lat = Cesium.Math.toDegrees(cartographic.latitude)
    polygonObj.lng = Cesium.Math.toDegrees(cartographic.longitude)
    polygonObj.alt = cartographic.height

    editPoints.push(polygonObj)

    const point = [polygonObj.lng, polygonObj.lat, polygonObj.alt]

    points = editPoints.map((item: any) => {
      return Cesium.Cartesian3.fromDegrees(item.lng, item.lat, editPoints[0].alt)
    })

    window.GPoint.add({
      name: '1', //不可重复
      parentName: 'assistPoint',
      option: {
        position: point,
        url: requireImage('common/redCircle.png'), //图标地址
        scale: 0.1,
        pixelOffset: [0, 0],
      },
    })

    if (points.length >= 3) {
      //计算面积
      area = window.cesiumMapTool.measureCar3Area(points).toFixed(2)

      if (gatherPolygon == null) {
        const option = {
          name: '2',
          parentName: 'measureMarker',
          option: {
            points: points,
            centerpos: window.cesiumMapTool.getPolygonCenter(points),
            label: {
              text: `面积：${area}㎡`,
              font: '18px san-serif',
              pixelOffset: new Cesium.Cartesian2(0, -10),
              showBackground: true, //是否显示背景
              backgroundColor: new Cesium.Color(0.165, 0.165, 0.165, 0.8), //背景颜色
              backgroundPadding: new Cesium.Cartesian2(7, 5), //背景边距
              fillColor: Cesium.Color.WHITE, //填充色
              outlineColor: Cesium.Color.BLACK, //外线颜色
              outlineWidth: 1.0, //外线宽
              disableDepthTestDistance: Number.POSITIVE_INFINITY,
            },
            polygon: {
              color: Cesium.Color.fromCssColorString('red').withAlpha(0.5),
              material: Cesium.Color.GREENYELLOW.withAlpha(0.5),
              distanceDisplayCondition: Cesium.DistanceDisplayCondition(10, 6000),
            },
          },
        }
        gatherPolygon = window.GPolygon.add(option)
      } else {
        //修改体的点位置信息
        gatherPolygon.polygon.hierarchy = new Cesium.CallbackProperty(function (
          time: string,
          result: any
        ) {
          const hierarchyTemp = new Cesium.PolygonHierarchy(points, null)
          return hierarchyTemp
        },
        false)
        //修改面的标注中心点位置信息
        gatherPolygon.position = window.cesiumMapTool.getPolygonCenter(points)
        gatherPolygon.label.text = `面积：${area}㎡`
      }
    }
  }, Cesium.ScreenSpaceEventType.LEFT_CLICK)

  // 对鼠标右键按下事件的监听,右键结束绘制
  viewer.screenSpaceEventHandler.setInputAction(function (rightClick: any) {
    // 如果小于三个点就结束绘制则提示用户
    if (points.length < 3) {
      return ElMessage.warning('必须绘制三个点')
    }

    //鼠标变成默认
    if (dom) {
      dom.style.cursor = 'default'
    }

    //移除标绘辅助点
    window.GPoint.removeByPatName('assistPoint')

    points = editPoints.map((item: any) => {
      return Cesium.Cartesian3.fromDegrees(item.lng, item.lat, editPoints[0].alt)
    })

    //移除事件
    viewer.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK)
    viewer.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.RIGHT_CLICK)
    // 隐藏 下方提示
    const chemicalStore = useChemicalStore()
    chemicalStore.tipsPageShow = false

    warLoadFeatureClick() //监听要素点击事件
  }, Cesium.ScreenSpaceEventType.RIGHT_CLICK)
}

/** 根据是否在模型上 使用不同的拾取坐标方法 */
function pickPosition(viewer: any, position: any) {
  let cartesian
  // 判断是否在模型上
  const pickedObject = viewer.scene.pick(position)

  if (Cesium.defined(pickedObject)) {
    //在模型上
    console.log('模型上')
    cartesian = viewer.scene.pickPosition(position)
  } else {
    //在模型外
    console.log('模型外')
    const ray = viewer.camera.getPickRay(position)
    cartesian = viewer.scene.globe.pick(ray, viewer.scene)
  }

  if (pickedObject?.id instanceof Cesium.Entity) {
    return { cartesian, type: 'Entity' }
  }

  return { cartesian }
}
